
#include "StdAfx.h"
#include "BaseDefine.h"
#include "ShellConnect.h"
#include "Tokenizer.h"

#ifndef WIN32
char* strupr( char* str ){
	char* orig = str;

	for ( ; *str != '\0'; str++ )
		*str = toupper(*str);

	return orig;
}
#endif

void getInt2Time( int time, char* ret_buf ){
	time_t  tTime = time;
	
#ifdef WIN32
	struct tm* tm_ptr = localtime( &tTime );
#else
	struct tm tm_ptr_ret;
	struct tm* tm_ptr = localtime_r( &tTime, &tm_ptr_ret );
#endif

#ifdef WIN32
	_snprintf( ret_buf, 128, "%d-%d-%d-%d:%d:%d", \
			(tm_ptr->tm_year + 1900), (tm_ptr->tm_mon + 1), (tm_ptr->tm_mday), \
			(tm_ptr->tm_hour), (tm_ptr->tm_min), (tm_ptr->tm_sec) );
#else	
	snprintf( ret_buf, 128, "%d-%d-%d-%d:%d:%d", \
			(tm_ptr->tm_year + 1900), (tm_ptr->tm_mon + 1), (tm_ptr->tm_mday), \
			(tm_ptr->tm_hour), (tm_ptr->tm_min), (tm_ptr->tm_sec) );
#endif
}

void getInt2IP( unsigned int ip, char* ret_buf ){
	union 
	{
		unsigned int nIP;
		byte szIP[4];
	} uniIP;
	
	uniIP.nIP = ip;	
	sprintf( ret_buf, "%d.%d.%d.%d", uniIP.szIP[0], uniIP.szIP[1], uniIP.szIP[2], uniIP.szIP[3] );
}

SystemInfomation::SystemInfomation(){
}

SystemInfomation::~SystemInfomation(){
}

int SystemInfomation::get_cpu_count(){
	// Get the logical and physical processor counts:	
	int logicalProcessors = LogicalProcessorsPerPackage();
	int physicalProcessors = 0;

#ifdef WIN32
	SYSTEM_INFO si;
	ZeroMemory( &si, sizeof(si) );

	GetSystemInfo( &si );

	physicalProcessors = (BYTE)(si.dwNumberOfProcessors / logicalProcessors);
	logicalProcessors *= physicalProcessors;

	// Make sure I always report at least one, when running WinXP with the /ONECPU switch, 
	// it likes to report 0 processors for some reason.	
	if( physicalProcessors == 0 && logicalProcessors == 0 ){		
		physicalProcessors = 1;
		logicalProcessors = 1;
	}
#else
	// TODO: poll /dev/cpuinfo when we have some benefits from multithreading
	//err
#endif

	return physicalProcessors;
}

int SystemInfomation::is_available_iocp(){
	#ifdef WIN32
	static char ver[ DEF_STR_TMP ];
	memset( ver, 0, DEF_STR_TMP );

	OSVERSIONINFO verOS;
	memset( &verOS, 0, sizeof( verOS ) );
	
	verOS.dwOSVersionInfoSize = sizeof( verOS );
	GetVersionEx( &verOS );

	if( verOS.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ){
		if( verOS.dwMinorVersion == 0 )
			return 0;
		else if( verOS.dwMinorVersion == 10 )
			return 0;
		if( verOS.dwMinorVersion == 90 )
			return 0;
	}
	else if( verOS.dwPlatformId == VER_PLATFORM_WIN32_NT ){
		if( verOS.dwMajorVersion == 3 )
			return 0;
		else if( verOS.dwMajorVersion == 4 )
			return 0;
		else if( verOS.dwMajorVersion == 5 ){
			if( verOS.dwMinorVersion == 0 )
				return 1;
			else if( verOS.dwMinorVersion == 1 )
				return 1;
			else if( verOS.dwMinorVersion == 2 )
				return 1;
		}
	}
#endif

	return 0;
}

char* SystemInfomation::get_os_name(){
#ifdef WIN32
	static char ver[ DEF_STR_TMP ];
	memset( ver, 0, DEF_STR_TMP );

	OSVERSIONINFO verOS;
	memset( &verOS, 0, sizeof( verOS ) );
	
	verOS.dwOSVersionInfoSize = sizeof( verOS );
	GetVersionEx( &verOS );

	if( verOS.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ){
		if( verOS.dwMinorVersion == 0 )
			strcpy( ver, "Windows 95" );
		else if( verOS.dwMinorVersion == 10 )
			strcpy( ver, "Windows 98" );
		if( verOS.dwMinorVersion == 90 )
			strcpy( ver, "Windows ME" );
	}
	else if( verOS.dwPlatformId == VER_PLATFORM_WIN32_NT ){
		if( verOS.dwMajorVersion == 3 )
			strcpy( ver, "Windows NT 3.51" );
		else if( verOS.dwMajorVersion == 4 )
			strcpy( ver, "Windows NT 4" );
		else if( verOS.dwMajorVersion == 5 ){
			if( verOS.dwMinorVersion == 0 )
				strcpy( ver, "Windows 2000" );
			else if( verOS.dwMinorVersion == 1 )
				strcpy( ver, "Windows XP" );
			else if( verOS.dwMinorVersion == 2 )
				strcpy( ver, "Windows 2003 Server" );
		}
	}

	if( verOS.szCSDVersion[0] != 0 ){
		strcat( ver, " " );
		strcat( ver, verOS.szCSDVersion );
	}

	int size = strlen( ver );

	sprintf( &(ver[ size ]), " (%d.%d.%d)", verOS.dwMajorVersion, verOS.dwMinorVersion, verOS.dwBuildNumber );
	
	return ver;

#else
	ShellConnect shell;

	if( shell.command( "uname -r" ) <= 0 )	
		return 0;

	return (char*)shell.getBuffer();	
#endif

	return 0;
}

int SystemInfomation::get_linux_kernel_version( int idx ){
	ShellConnect shell;
	Tokenizer tok;
	std::vector< int > kernel_version_numeric;
	
	if( shell.command( "uname -r" ) <= 0 )
		return 0;

	char* result = (char*)shell.getBuffer();	
	int split_count = tok.splitTokenNumeric( result );

	char* numeric_value = 0;
	size_t value = 0;
	
	while( numeric_value = tok.getNextToken() ){
		value = atoi( numeric_value );
		kernel_version_numeric.push_back( value );
	} 

	if( kernel_version_numeric.size() <= (size_t)idx )
		return 0;

	return kernel_version_numeric[ idx ];
}

ArgInfo::ArgInfo( int count, char** args ){
	for( int i = 0 ; i < count ; i++ ){
		args_.push_back( args[i] );
	}	
}

ArgInfo::~ArgInfo(){
}

int ArgInfo::size(){
	return args_.size();
}

char* ArgInfo::toCharacters( unsigned int idx ){
	if( args_.size() <= idx )
		return 0;

	return (char*)args_[idx].c_str();	
}

int ArgInfo::toInt( unsigned int idx ){
	if( args_.size() <= idx )
		return 0;

	const char* data = args_[idx].c_str();
	return atoi( data );
}

float ArgInfo::toFloat( unsigned int idx ){
	if( args_.size() <= idx )
		return 0.0;

	const char* data = args_[idx].c_str();
	return (float)atof( data );
}

__int64 ArgInfo::toInt64( unsigned int idx ){
	if( args_.size() <= idx )
		return 0;

	const char* data = args_[idx].c_str();

#ifdef WIN32
	return _atoi64( data );
#else
	return atoll( data );
#endif	
}

ErrorInformation::ErrorInformation(){	
	func_ = "";
	memset( error_msg_, 0, DEF_ERROR_MSG_LEN );
	error_line_ = 0;
	error_code_ = 0;
}

ErrorInformation::~ErrorInformation(){
}

void ErrorInformation::error( char* func, int line ){
	if( func )
		func_ = func;

	error_line_ = line;

#ifdef WIN32
	memset( error_msg_, 0, DEF_ERROR_MSG_LEN );

	error_code_ = GetLastError();	

	FormatMessage( 
		(DWORD) ( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS ),
		0, (DWORD)error_code_,
		(DWORD) (MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) ), // Default language
		(LPTSTR)error_msg_, (DWORD)DEF_ERROR_MSG_LEN, 0	);	
#else
	error_code_ = errno;

	char* tmp = strerror( error_code_ );
	strncpy( error_msg_, tmp, strlen( tmp ) );
#endif
}

void ErrorInformation::error( char* func, int line, __int64 error_code, char* msg ){
	if( func )
		func_ = func;

	error_line_ = line;

	error_code_ = error_code;
	strncpy( error_msg_, msg, strlen( msg ) );
}